using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using System.Threading.Tasks;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services
{
    /// <summary>
    /// 内容服务实现
    /// 提供内容模型和内容项管理的业务逻辑实现，包括创建、查询、更新和删除操作
    /// </summary>
    public class ContentService : IContentAppService
    {
        /// <summary>
        /// 内容仓储接口
        /// </summary>
        private readonly Domain.Interfaces.IContentRepository _contentRepository;

        /// <summary>
        /// 初始化内容服务实例
        /// </summary>
        /// <param name="contentRepository">内容仓储接口实例</param>
        public ContentService(Domain.Interfaces.IContentRepository contentRepository)
        {
            _contentRepository = contentRepository;
        }

        /// <summary>
        /// 异步获取系统中所有内容模型
        /// </summary>
        /// <returns>内容模型DTO集合</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>检索系统中所有已定义的内容模型</description></item>
        /// <item><description>自动将领域实体转换为DTO格式</description></item>
        /// <item><description>处理字段序列化和反序列化</description></item>
        /// </list>
        /// 
        /// <para>数据处理：</para>
        /// <list type="bullet">
        /// <item><description>JSON字段自动反序列化为强类型对象</description></item>
        /// <item><description>空字段集合安全处理</description></item>
        /// <item><description>确保返回数据的完整性</description></item>
        /// </list>
        /// 
        /// <para>使用场景：</para>
        /// <list type="bullet">
        /// <item><description>内容管理系统模型列表展示</description></item>
        /// <item><description>模型选择器数据源</description></item>
        /// <item><description>系统配置和管理界面</description></item>
        /// </list>
        /// </remarks>
        /// <exception cref="InvalidOperationException">数据访问失败时抛出</exception>
    /// <exception cref="System.Text.Json.JsonException">字段JSON反序列化失败时抛出</exception>
        public async Task<IEnumerable<Application.DTOs.ContentModelDto>> GetAllModelsAsync()
        {
            var models = await _contentRepository.GetAllModelsAsync();
            return models.Select(m => new Application.DTOs.ContentModelDto
            {
                Id = m.Id,
                Name = m.Name,
                Description = m.Description,
                Fields = m.Fields != null ? System.Text.Json.JsonSerializer.Deserialize<List<Application.DTOs.FieldDto>>(m.Fields) ?? new List<Application.DTOs.FieldDto>() : new List<Application.DTOs.FieldDto>()
            });
        }

        /// <summary>
        /// 根据标识符异步获取指定内容模型
        /// </summary>
        /// <param name="id">内容模型的唯一标识符</param>
        /// <returns>匹配的内容模型DTO，不存在时返回null</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>根据ID精确查找内容模型</description></item>
        /// <item><description>安全处理不存在的模型情况</description></item>
        /// <item><description>自动转换为业务层DTO格式</description></item>
        /// </list>
        /// 
        /// <para>数据转换：</para>
        /// <list type="bullet">
        /// <item><description>领域实体到DTO的完整映射</description></item>
        /// <item><description>字段定义JSON反序列化</description></item>
        /// <item><description>空值安全处理</description></item>
        /// </list>
        /// 
        /// <para>使用场景：</para>
        /// <list type="bullet">
        /// <item><description>模型详情页面展示</description></item>
        /// <item><description>编辑操作前的数据加载</description></item>
        /// <item><description>业务逻辑中的模型验证</description></item>
        /// </list>
        /// </remarks>
        /// <exception cref="ArgumentException">ID参数无效时抛出</exception>
        /// <exception cref="InvalidOperationException">数据访问失败时抛出</exception>
        public async Task<Application.DTOs.ContentModelDto?> GetModelByIdAsync(long id)
        {
            var model = await _contentRepository.GetModelByIdAsync(id);
            if (model == null) return null;
            return new Application.DTOs.ContentModelDto
            {
                Id = model.Id,
                Name = model.Name,
                Description = model.Description,
                Fields = model.Fields != null ? System.Text.Json.JsonSerializer.Deserialize<List<Application.DTOs.FieldDto>>(model.Fields) ?? new List<Application.DTOs.FieldDto>() : new List<Application.DTOs.FieldDto>()
            };
        }

        /// <summary>
        /// 异步创建新的内容模型
        /// </summary>
        /// <param name="model">要创建的内容模型DTO，包含名称、描述和字段定义</param>
        /// <returns>创建操作的异步任务</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>创建新的内容模型实体</description></item>
        /// <item><description>自动处理字段定义的JSON序列化</description></item>
        /// <item><description>确保模型数据的完整性和一致性</description></item>
        /// </list>
        /// 
        /// <para>数据处理：</para>
        /// <list type="bullet">
        /// <item><description>DTO到领域实体的完整转换</description></item>
        /// <item><description>字段集合自动JSON序列化</description></item>
        /// <item><description>模型元数据标准化处理</description></item>
        /// </list>
        /// 
        /// <para>业务规则：</para>
        /// <list type="bullet">
        /// <item><description>模型名称必须唯一</description></item>
        /// <item><description>字段定义格式必须符合规范</description></item>
        /// <item><description>自动生成创建时间戳</description></item>
        /// </list>
        /// 
        /// <para>使用场景：</para>
        /// <list type="bullet">
        /// <item><description>动态内容类型定义</description></item>
        /// <item><description>低代码平台模型设计</description></item>
        /// <item><description>内容管理系统扩展</description></item>
        /// </list>
        /// </remarks>
        /// <exception cref="ArgumentNullException">模型参数为空时抛出</exception>
        /// <exception cref="InvalidOperationException">模型创建失败时抛出</exception>
    /// <exception cref="System.Text.Json.JsonException">字段序列化失败时抛出</exception>
        public async Task CreateModelAsync(Application.DTOs.ContentModelDto model)
        {
            var entity = new Domain.Entities.ContentModel
            {
                Id = model.Id,
                Name = model.Name,
                Description = model.Description,
                Fields = System.Text.Json.JsonSerializer.Serialize(model.Fields)
            };
            await _contentRepository.CreateModelAsync(entity);
        }

        /// <summary>
        /// 更新内容模型
        /// 根据指定ID更新现有的内容模型信息
        /// </summary>
        /// <param name="id">内容模型标识符</param>
        /// <param name="model">更新后的内容模型DTO</param>
        /// <returns>更新操作的异步任务</returns>
        public async Task UpdateModelAsync(long id, Application.DTOs.ContentModelDto model)
        {
            var entity = new Domain.Entities.ContentModel
            {
                Id = model.Id,
                Name = model.Name,
                Description = model.Description,
                Fields = System.Text.Json.JsonSerializer.Serialize(model.Fields)
            };
            await _contentRepository.UpdateModelAsync(id, entity);
        }

        /// <summary>
        /// 删除内容模型
        /// 删除指定标识符的内容模型及其相关数据
        /// </summary>
        /// <param name="id">内容模型标识符</param>
        /// <returns>删除操作的异步任务</returns>
        public async Task DeleteModelAsync(long id)
        {
            await _contentRepository.DeleteModelAsync(id);
        }

        /// <summary>
        /// 获取内容模型的字段列表
        /// 检索指定内容模型的所有字段定义
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <returns>字段DTO列表</returns>
        public async Task<IEnumerable<Application.DTOs.FieldDto>> GetFieldsAsync(long modelId)
        {
            var fields = await _contentRepository.GetFieldsAsync(modelId);
            return fields.Select(f => new Application.DTOs.FieldDto
            {
                Id = f.Id,
                Name = f.Name,
                Type = f.Type,
                IsRequired = f.IsRequired,
                DefaultValue = null,
                Options = null
            });
        }

        /// <summary>
        /// 为内容模型添加字段
        /// 在指定的内容模型中添加新的字段定义
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="field">要添加的字段DTO</param>
        /// <returns>添加操作的异步任务</returns>
        public async Task AddFieldAsync(long modelId, Application.DTOs.FieldDto field)
        {
            var entity = new Domain.Entities.Field
            {
                Id = field.Id,
                Name = field.Name,
                Type = field.Type,
                IsRequired = field.IsRequired,
                Description = null,
                Order = 0
            };
            await _contentRepository.AddFieldAsync(modelId, entity);
        }

        /// <summary>
        /// 更新内容模型字段
        /// 修改指定字段的属性配置
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="fieldId">字段标识符</param>
        /// <param name="field">更新后的字段DTO</param>
        /// <returns>更新操作的异步任务</returns>
        public async Task UpdateFieldAsync(long modelId, long fieldId, Application.DTOs.FieldDto field)
        {
            var entity = new Domain.Entities.Field
            {
                Id = field.Id,
                Name = field.Name,
                Type = field.Type,
                IsRequired = field.IsRequired,
                Description = null,
                Order = 0
            };
            await _contentRepository.UpdateFieldAsync(modelId, fieldId, entity);
        }

        /// <summary>
        /// 删除内容模型字段
        /// 从指定内容模型中移除字段定义
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="fieldId">字段标识符</param>
        /// <returns>删除操作的异步任务</returns>
        public async Task DeleteFieldAsync(long modelId, long fieldId)
        {
            await _contentRepository.DeleteFieldAsync(modelId, fieldId);
        }

        /// <summary>
        /// 分页获取内容项
        /// 检索指定内容模型的内容项列表，支持分页查询
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="page">页码，默认为1</param>
        /// <param name="limit">每页记录数，默认为10</param>
        /// <returns>内容项DTO列表</returns>
        public async Task<IEnumerable<Application.DTOs.ContentItemDto>> GetItemsAsync(long modelId, int page = 1, int limit = 10)
        {
            var items = await _contentRepository.GetItemsAsync(modelId, page, limit);
            return items.Select(i => new Application.DTOs.ContentItemDto
            {
                Id = i.Id,
                ModelId = i.ModelId,
                Data = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(i.Data) ?? new Dictionary<string, object>(),
                Status = i.Status
            });
        }

        /// <summary>
        /// 创建新的内容项
        /// 在指定内容模型中创建新的内容实例
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="item">要创建的内容项DTO</param>
        /// <returns>创建操作的异步任务</returns>
        public async Task CreateItemAsync(long modelId, Application.DTOs.ContentItemDto item)
        {
            var entity = new Domain.Entities.ContentItem
            {
                Id = item.Id,
                ModelId = item.ModelId,
                Data = System.Text.Json.JsonSerializer.Serialize(item.Data),
                Status = item.Status,
                CreatedAt = System.DateTime.UtcNow,
                UpdatedAt = System.DateTime.UtcNow
            };
            await _contentRepository.CreateItemAsync(modelId, entity);
        }

        /// <summary>
        /// 根据ID获取内容项
        /// 检索指定内容项的详细信息
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="itemId">内容项标识符</param>
        /// <returns>内容项DTO，如果不存在则返回null</returns>
        public async Task<Application.DTOs.ContentItemDto?> GetItemByIdAsync(long modelId, long itemId)
        {
            var item = await _contentRepository.GetItemByIdAsync(modelId, itemId);
            if (item == null) return null;
            return new Application.DTOs.ContentItemDto
            {
                Id = item.Id,
                ModelId = item.ModelId,
                Data = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(item.Data) ?? new Dictionary<string, object>(),
                Status = item.Status
            };
        }

        /// <summary>
        /// 更新内容项
        /// 修改指定内容项的数据和状态
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="itemId">内容项标识符</param>
        /// <param name="item">更新后的内容项DTO</param>
        /// <returns>更新操作的异步任务</returns>
        public async Task UpdateItemAsync(long modelId, long itemId, Application.DTOs.ContentItemDto item)
        {
            var entity = new Domain.Entities.ContentItem
            {
                Id = item.Id,
                ModelId = item.ModelId,
                Data = System.Text.Json.JsonSerializer.Serialize(item.Data),
                Status = item.Status,
                CreatedAt = System.DateTime.UtcNow,
                UpdatedAt = System.DateTime.UtcNow
            };
            await _contentRepository.UpdateItemAsync(modelId, itemId, entity);
        }

        /// <summary>
        /// 删除内容项
        /// 从系统中移除指定的内容项
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="itemId">内容项标识符</param>
        /// <returns>删除操作的异步任务</returns>
        public async Task DeleteItemAsync(long modelId, long itemId)
        {
            await _contentRepository.DeleteItemAsync(modelId, itemId);
        }

        /// <summary>
        /// 获取内容项状态
        /// 查询指定内容项的当前状态信息
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="itemId">内容项标识符</param>
        /// <returns>内容项状态对象</returns>
        public async Task<object?> GetItemStatusAsync(long modelId, long itemId)
        {
            var item = await _contentRepository.GetItemByIdAsync(modelId, itemId);
            if (item == null)
                return null;

            return new
            {
                Id = item.Id,
                ModelId = item.ModelId,
                Status = item.Status,
                CreatedAt = item.CreatedAt,
                UpdatedAt = item.UpdatedAt
            };
        }

        /// <summary>
        /// 修改内容项状态
        /// 变更指定内容项的状态（如草稿、已发布、已下线等）
        /// </summary>
        /// <param name="modelId">内容模型标识符</param>
        /// <param name="itemId">内容项标识符</param>
        /// <param name="status">目标状态</param>
        /// <returns>状态修改操作的异步任务</returns>
        public async Task ChangeItemStatusAsync(long modelId, long itemId, string status)
        {
            var item = await _contentRepository.GetItemByIdAsync(modelId, itemId);
            if (item != null)
            {
                item.Status = status;
                item.UpdatedAt = DateTime.UtcNow;
                await _contentRepository.UpdateItemAsync(modelId, itemId, item);
            }
        }
    }
}
